/**
 * Created by henian.xu on 2018/11/23.
 * 拦截器抽象类 不可实例化
 */

import Axios from 'axios';
import defaultConfig from './config';

/**
 * 创建取消令牌
 * @returns {CancelTokenSource}
 */
function createCancelToken() {
    const cancelToken = Axios.CancelToken;
    return cancelToken.source();
}

class InterceptorBase {
    constructor(context) {
        const { $axios } = context;
        this.ctx = context;
        $axios.createCancelToken = createCancelToken;
        this.$axios = $axios;
        this.superMethods = {};
    }

    _init() {
        const { $axios } = this;
        ['onRequest', 'onResponse', 'onError', 'onRequestError', 'onResponseError'].forEach(key => {
            const method = this[key];
            if (!method) return;
            $axios[key](method.bind(this));
        });
        this._interceptor();
    }
    _interceptor(methods = ['get', 'post']) {
        const { $axios, superMethods } = this;
        // 获取已实现方法
        methods = methods.filter(method => typeof this[method] === 'function' && typeof $axios[method] === 'function');
        methods.forEach(method => {
            superMethods[method] = $axios[method];
            $axios[method] = this[method].bind(this);
        });
    }
    _setInsideConfig(cfg = {}) {
        cfg._cancelSource = cfg._cancelSource || createCancelToken();
        return {
            ...defaultConfig,
            // 默认:false; 是否重复发送请求
            _isRepeat: false,
            // 默认:true; 当不可重复请求时, true:取消之前的请求; false:取消之后的请求
            _isCancelBefore: true,
            // 默认:false; 是否自已处理错误请求，false 框架统一处理,true:框架不做任何处理
            _isHandleError: false,
            // 默认:true; 是否拼接 baseUrl
            _joinBaseUrl: true,
            ...cfg,
            cancelToken: cfg._cancelSource.token,
        };
    }
    get(url, params = {}, cfg = {}) {
        cfg = this._setInsideConfig(cfg);
        params._T = new Date().getTime();
        return this.superMethods.get(url, {
            ...cfg,
            params,
        });
    }
    post(url, params = {}, cfg = {}) {
        cfg = this._setInsideConfig({
            _isCancelBefore: false, // 默认值与get的相反,取消之后的请求
            ...cfg,
        });
        return this.superMethods.post(url, params, cfg);
    }

    // onRequest(config) {}
    // onResponse(response) {}
    onError(error) {
        const { response } = error;
        if (response && +response.status) {
            const { status, config, data } = response;
            if (config._isHandleError) return; // 调用接口已经处理错误
            console.log(config._isHandleError);
            const message = data.message;
            this.ctx.redirect(`/error?status=${status}&message=${message}`);
        }
    }
    // onRequestError(error) {}
    // onResponseError(error) {}
}

class ServerInterceptor extends InterceptorBase {
    constructor(context) {
        super(context);
        this._init();
    }
    onRequest() {
        console.log('ServerInterceptor');
    }
}
class clientInterceptor extends InterceptorBase {
    constructor(context) {
        super(context);
        this._init();
    }
    onRequest() {
        console.log('clientInterceptor');
    }
}

export default context => {
    process.server && new ServerInterceptor(context);
    process.client && new clientInterceptor(context);
};
